package ade.prime.activity;

import ade.prime.model.Lesson;
import ade.prime.model.Schedule;
import ade.prime.service.AdeWebService;
import ade.prime.service.AdeWebServiceApi;
import ade.prime.service.AdeWebServiceListener;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

import com.actionbarsherlock.app.SherlockActivity;

/**
 * Handles the connection to the service for sub-classes of this class.
 * 
 * @author		Schnell Michaël
 * @version		1.0
 */
public class AdeWebActivity extends SherlockActivity {

	protected static final String TAG = AdeWebActivity.class.getSimpleName() ;

	protected AdeWebServiceApi serviceApi ;

	protected ServiceConnection serviceConnection ;

	protected AdeWebServiceListenerAdapter listener ;

	/**
	 * Binds this activity to the AdeWeb service.
	 */
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState) ;

		// Start the service if it is not already running
		Intent serviceIntent = new Intent(AdeWebService.class.getName()) ;
		this.startService(serviceIntent) ;

		// Binds the activity to the service and adds a connection listener
		this.serviceConnection = this.getServiceConnection() ;
		this.bindService(serviceIntent, this.serviceConnection, 0) ;
	}// onCreate(Bundle)
	
	/**
	 * Releases the bound service.
	 */
	@Override
	protected void onDestroy() {
		try {
			this.serviceApi.removeListener(this.listener.getId()) ;
			unbindService(this.serviceConnection) ;
		} catch (RemoteException re) {
			// TODO: handle exception
			Log.d(TAG, "Failed to unbind from the service", re) ; //$NON-NLS-1$
		}// try
		
		super.onDestroy() ;
	}// onDestroy()

	protected ServiceConnection getServiceConnection() {
		return new ServiceConnectionAdapter(this) ;
	}// getServiceConnection()

	protected AdeWebServiceListener getAdeWebServiceListener() {
		return new AdeWebServiceListenerAdapter(this) ;
	}// getServiceConnection()

	protected class ServiceConnectionAdapter implements ServiceConnection {
		
		protected AdeWebActivity activity ;

		protected ServiceConnectionAdapter(AdeWebActivity activity) {
			super() ;
			this.activity = activity ;
		}// ServiceConnectionAdapter(AdeWebActivity)

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
//			Log.d(TAG, "Service connection established"); //$NON-NLS-1$

			// Retrieve the client side of the IPC connection
			this.activity.serviceApi = AdeWebServiceApi.Stub.asInterface(service) ;
			this.activity.listener = (AdeWebServiceListenerAdapter) 
					this.activity.getAdeWebServiceListener() ;
			try {
				int id = this.activity.serviceApi.addListener(this.activity.listener) ;
				this.activity.listener.setId(id) ;
			} catch (RemoteException e) {
				Log.e(TAG, "Failed to add listener", e); //$NON-NLS-1$
			}// try
		}// onServiceConnected(ComponentName, IBinder)

		@Override
		public void onServiceDisconnected(ComponentName name) {
//			Log.d(TAG, "Service connection closed");      //$NON-NLS-1$
		}// onServiceDisconnected(ComponentName)

	}// class ServiceConnectionAdapter
	
	protected class AdeWebServiceListenerAdapter extends AdeWebServiceListener.Stub {
		
		protected int id ;
		
		protected AdeWebActivity activity ;
		
		protected AdeWebServiceListenerAdapter(AdeWebActivity activity) {
			super() ;
			this.activity = activity ;
		}// AdeWebServiceListenerAdapter(AdeWebActivity)
	
		/**
		 * @param id the id to set
		 */
		public void setId(int id) {
			this.id = id;
		}// setId(int)
		
		/**
		 * @return the id of this listener
		 */
		@Override
		public int getId() {
			return this.id ;
		}// getId()

		@Override
		public final void handleNewSchedule(final Schedule newSchedule) {
			final AdeWebServiceListenerAdapter adapter = this ;
			this.activity.runOnUiThread(new Runnable() {
				@Override
				public void run() {
					adapter.handleNewScheduleRunnable(newSchedule) ;
				}// run()
			}) ;
		}// handleNewSchedule(Schedule)

		@Override
		public final void handleModifiedSchedule(final Schedule newSchedule) {
			final AdeWebServiceListenerAdapter adapter = this ;
			this.activity.runOnUiThread(new Runnable() {
				@Override
				public void run() {
					adapter.handleModifiedScheduleRunnable(newSchedule) ;
				}// run()
			}) ;
		}// handleModifiedSchedule(Schedule)

		@Override
		public final void handleRemovedSchedule(final Schedule newSchedule) {
			final AdeWebServiceListenerAdapter adapter = this ;
			this.activity.runOnUiThread(new Runnable() {
				@Override
				public void run() {
					adapter.handleRemovedScheduleRunnable(newSchedule) ;
				}// run()
			}) ;
		}// handleRemovedSchedule(Schedule)

		@Override
		public final void handleModifiedScheduleState(final Schedule newSchedule) {
			final AdeWebServiceListenerAdapter adapter = this ;
			this.activity.runOnUiThread(new Runnable() {
				@Override
				public void run() {
					adapter.handleModifiedScheduleStateRunnable(newSchedule) ;
				}// run()
			}) ;
		}// handleModifiedScheduleState(Schedule)

		@Override
		public final void handleModifiedLessonType(final Lesson modifiedLesson) {
			final AdeWebServiceListenerAdapter adapter = this ;
			this.activity.runOnUiThread(new Runnable() {
				@Override
				public void run() {
					adapter.handleModifiedLessonTypeRunnable(modifiedLesson) ;
				}// run()
			}) ;
		}// handleModifiedLessonType(Lesson)

		@Override
		public final void handleRemovedLessonHistory(final long lessonId) {
			final AdeWebServiceListenerAdapter adapter = this ;
			this.activity.runOnUiThread(new Runnable() {
				@Override
				public void run() {
					adapter.handleRemovedLessonHistoryRunnable(lessonId) ;
				}// run()
			}) ;
		}// handleRemovedLessonHistory(long)

		@Override
		public final void handleModifiedOptions() {
			final AdeWebServiceListenerAdapter adapter = this ;
			this.activity.runOnUiThread(new Runnable() {
				@Override
				public void run() {
					adapter.handleModifiedOptionsRunnable() ;
				}// run()
			}) ;
		}// handleModifiedOptionsRunnable(AdeWebOptions)
		
		@SuppressWarnings("unused")
		protected void handleNewScheduleRunnable(Schedule newSchedule) {
			/* Empty implantation. */
		}// handleNewScheduleRunnable(Schedule)

		@SuppressWarnings("unused")
		protected void handleModifiedScheduleRunnable(Schedule modifiedSchedule) {
			/* Empty implantation. */
		}// handleModifiedScheduleRunnable(Schedule)

		@SuppressWarnings("unused")
		protected void handleRemovedScheduleRunnable(Schedule removedSchedule) {
			/* Empty implantation. */
		}// handleRemovedScheduleRunnable(Schedule)

		@SuppressWarnings("unused")
		protected void handleModifiedScheduleStateRunnable(Schedule modifiedSchedule) {
			/* Empty implantation. */
		}// handleModifiedScheduleStateRunnable(Schedule)

		@SuppressWarnings("unused")
		protected void handleModifiedLessonTypeRunnable(Lesson modifiedLesson) {
			/* Empty implantation. */
		}// handleModifiedLessonTypeRunnable(Lesson)

		@SuppressWarnings("unused")
		protected void handleRemovedLessonHistoryRunnable(long lessonId) {
			/* Empty implantation. */
		}// handleRemovedLessonHistoryRunnable(long)
		
		protected void handleModifiedOptionsRunnable() {
			/* Empty implantation. */
		}// handleModifiedOptionsRunnable(AdeWebOptions)
		
	}// class AdeWebServiceListenerAdapter

}// class AdeWebActivity